﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace GameLogicProject
{
    class Player
    {
        // Player details
        public string Name { get; set; }

        
        
        // Output
        public int Budget { get; set; } //Dinheiro total actual

        public int ProductionRate { get; set; }

        public string SoldProductsCount { get; set; }
        public string InterestedClientsCount { get; set; }
        public string ComplaintsCount { get; set; }
        public string MediaReferencesCount { get; set; }

        //Historico de percentagens obtidas pelas opções do jogador
        public ArrayList PercentageLog { get; set; }

        // Arvore de escolhas do utilizador
        public Option ChoiceTree { get; set; }
        public Option ChosenMarket { get; set; }


        public Player(string name)
        {
            this.Name = name;
        }

        public double generateWeekIncome()
        {
            double strategy = this.getCurrentPercentagem();
            Random generatedRand = new Random();
            int randomNumber = generatedRand.Next(-(int)(strategy * 100.0), (int)(strategy * 100.0));
            Console.WriteLine("RandomNumber: " + randomNumber);
            int randomCentenas = generatedRand.Next(100);
            Console.WriteLine("RandomCenas: " + randomNumber);
            return ((strategy + (randomNumber / 1000.0)) * 100000.0) + randomCentenas;
        }

        //Permite escolher o mercado
        public Option chooseMarket()
        {
            Console.WriteLine("Escolher mercado: ");
            int j = 0;
            for (; j < this.ChoiceTree.Options.Count; j++)
            {
                Console.WriteLine("     " + j + " - " + this.ChoiceTree.Options[j].Name);
            }
            int opcMarket = -1;
            while (opcMarket < 0 || opcMarket >= this.ChoiceTree.Options.Count)
            {
                Console.Write("Opcao: ");
                opcMarket = int.Parse(Console.ReadLine());
            }

            this.ChoiceTree.Choice = opcMarket;

            ChosenMarket = this.ChoiceTree.Options[opcMarket];

            return this.ChosenMarket;
        }


        public void chooseTree()
        {
            Console.WriteLine("\nEscolher Estrategia");

            List<Option> escolhas = new List<Option>();


            escolhas.Add(this.ChosenMarket);

            while (escolhas.Count > 0)
            {
                //Console.WriteLine("ESCOLHAS:::: " + escolhas.Count);
                if (escolhas[0].finalNode == true)
                {
                    //Console.WriteLine("\nFinalNode: true");
                    if (escolhas[0].Options.Count > 0)
                    {
                        escolhas.Add(escolhas[0].chooseOption());
                        escolhas.RemoveAt(0);
                    }
                    else
                    {
                        escolhas.RemoveAt(0);
                    }
                }
                else
                {
                    //Console.WriteLine("\nFinalNode: false");
                    foreach (Option ramo in escolhas[0].Options)
                    {
                        escolhas.Add(ramo);
                    }
                    escolhas.RemoveAt(0);
                }
            }
        }

        public double getCurrentPercentagem()
        {
            return this.ChosenMarket.generatePercentage();
        }

        public ArrayList getTalks(int numTalks)
        {
            return this.ChoiceTree.generateTalks(numTalks);
        }

        // Define mercado
        public void setMarket(int index)
        {
            ChoiceTree.Choice = index;
        }

        public Option getMarket()
        {
            if (ChoiceTree.Choice < 0)
                throw new Exception("The market has not been chosen yet!");

            return (Option) ChoiceTree.Options[ChoiceTree.Choice];
        }

        // Define opções do mercado consoante o nodeType
        // Pode definir tipo de 'SegmentationLevel', 'Strategy', 'Production' ou 'Company'
        public void setMarketOptions(NodeType nodeType, int index)
        {
            if (ChoiceTree.Choice < 0) {
                throw new Exception("The market has not been chosen yet!");
            }
            
            Option market = (Option) ChoiceTree.Options[ChoiceTree.Choice];
            foreach( Option opt in market.Options)
            {
                if (opt.Type == nodeType)
                {
                    opt.Choice = index;
                }
            }            
        }

        //Retorna o filho do nó market, do tipo nodeType
        public Option getMarketOptions(NodeType nodeType)
        {
            if (ChoiceTree.Choice < 0)
                throw new Exception("The market has not been chosen yet!");

            Option market = (Option)ChoiceTree.Options[ChoiceTree.Choice];
            foreach (Option opt in market.Options)
            {
                if (opt.Type == nodeType)
                    return opt;
            }
            return null;
        }

        //Defines the player 'luck'
        public double getKarma()
        {
            double karmaValue = 0;

            karmaValue += compareWithLast();
            karmaValue += compareWithLog();

            return karmaValue;
        }

        private double compareWithLog()
        {
            if (this.PercentageLog.Count == 0)
                throw new Exception("PercentageLog is empty");

            double karmaValue = 0;

            if (this.PercentageLog.Count == 1)
            {
                // (PercentagemActual - 50%) / 10 
                // Valores (+) se percentagem > 50%
                // Valores (-) se percentagem < 50%
                karmaValue += (((int)this.PercentageLog[0] - 50) / 10);
            }
            else
            {
                ; //TODO
            }

            return karmaValue;
        }

        private double compareWithLast()
        {
            //throw new NotImplementedException();
            int currentPercentage   = (int)this.PercentageLog[this.PercentageLog.Count - 1];
            int lastPercentage      = (int)this.PercentageLog[this.PercentageLog.Count - 2];

            return (currentPercentage - lastPercentage);
        }

    }
}
